package com.ship.common.business.service.impl;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ship.common.business.service.BaseService;
import com.ship.common.core.base.PageBean;
import com.ship.common.core.mybatis.mapping.MappingContext;
import com.ship.common.core.utils.FieldUtil;
import com.ship.common.core.utils.SpringUtils;
import com.ship.common.core.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 31463
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T extends PageBean> extends ServiceImpl<M, T> implements BaseService<T> {

    private static final String SPLIT_TAG = "::";

    @Override
    public com.ship.common.core.base.Page<T> page(T t, QueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            queryWrapper = new QueryWrapper<>();
        }
        Page<T> page = new Page<T>();
        page.setOptimizeCountSql(true);
        int pageSize = (t.getPageSize() == null ? 10 : t.getPageSize());
        int pageNum = (t.getPageNum() == null ? 1 : t.getPageNum());
        page.setSize(pageSize);
        page.setCurrent(pageNum);
        this.handleWrapper(queryWrapper, t);
        IPage<T> iPage = this.getBaseMapper().selectPage(page, queryWrapper);
        return new com.ship.common.core.base.Page<>(iPage);
    }

    @Override
    public List<T> pageExportList(T t, QueryWrapper<T> queryWrapper, List<String> fieldList) {
        if (queryWrapper == null) {
            queryWrapper = new QueryWrapper<>();
        }
        this.handleWrapper(queryWrapper, t);

        if(fieldList != null && fieldList.size() > 0){
            StringBuilder query = new StringBuilder("id");
            for (String s : fieldList) {
                query.append(",").append(s);
            }
            queryWrapper.select(query.toString());
        }
        List<T> resultList = this.getBaseMapper().selectList(queryWrapper);
        return resultList;
    }

    @Override
    public com.ship.common.core.base.Page<T> page(T t) {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Page<T> page = new Page<T>();
        page.setOptimizeCountSql(true);
        int pageSize = (t.getPageSize() == null ? 10 : t.getPageSize());
        int pageNum = (t.getPageNum() == null ? 1 : t.getPageNum());
        page.setSize(pageSize);
        page.setCurrent(pageNum);
        this.handleWrapper(queryWrapper, t);
        IPage<T> iPage = this.getBaseMapper().selectPage(page, queryWrapper);
        return new com.ship.common.core.base.Page<>(iPage);
    }

    @Override
    public void handleWrapper(QueryWrapper<T> queryWrapper, T t) {
        if(t.getOrderField() != null){
            queryWrapper.orderByDesc(t.getOrderField());
        }else{
            queryWrapper.orderByDesc("id");
        }
//        if (!queryWrapper.isEmptyOfWhere()) {
//            return;
//        }
        this.handleCondition(queryWrapper, t);
        //拼装范围查询
        Object queryParamsObj = t.getQueryParams();
        if(queryParamsObj != null){
            Map<String,Object> queryParams = (Map<String, Object>)queryParamsObj ;
            for(Map.Entry entry : queryParams.entrySet()){
                String mapKey = (String) entry.getKey();
                String mapValue = (String)entry.getValue();
                if(StringUtils.isNotBlank(mapValue)){
                    if (mapKey.endsWith("Start")) {
                        queryWrapper.gt(StringUtil.humpToUnderline(mapKey.substring(0, mapKey.length() - 5)), mapValue);
                    }
                    if (mapKey.endsWith("End")) {
                        queryWrapper.lt(StringUtil.humpToUnderline(mapKey.substring(0, mapKey.length() - 3)), mapValue);
                    }
                }
            }
        }

        //兼容
        Map<String,Object> betweenParams = t.getBetweenParams();
        if(betweenParams != null){
            for(Map.Entry entry : betweenParams.entrySet()){
                String mapKey = (String) entry.getKey();
                Object mapValue = entry.getValue();
                if (mapKey.endsWith("Start")) {
                    queryWrapper.gt(StringUtil.humpToUnderline(mapKey.substring(0, mapKey.length() - 5)), mapValue);
                }
                if (mapKey.endsWith("End")) {
                    queryWrapper.lt(StringUtil.humpToUnderline(mapKey.substring(0, mapKey.length() - 3)), mapValue);
                }
            }
        }
    }

    @Override
    public List<T> listForSearchBox(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        this.handleWrapper(queryWrapper, t);
        return this.getBaseMapper().selectList(queryWrapper);
    }

    @Override
    public List<T> listByIds(List<Long> ids) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        if (ids.isEmpty()) {
            ids.add((long) -1);
        }
        queryWrapper.in("id", ids);
        return this.getBaseMapper().selectList(queryWrapper);
    }

    private void handleCondition(QueryWrapper<T> queryWrapper, T t) {
        for (Field field : FieldUtil.getAllFields(t.getClass())) {
            try {
                TableField tableField = field.getAnnotation(TableField.class);
                boolean exist = true;
                if (tableField != null) {
                    exist = tableField.exist();
                }
                String fieldName = field.getName();
//                if(StringUtils.equals("ids",fieldName)){
//                    Objects.requireNonNull(MappingContext.getMapping(List.class)).applyList(t, field, queryWrapper, "id");
//                    continue;
//                }
                boolean isListSearch = fieldName.endsWith("ListForSearch");
                if(!exist && !isListSearch){
                    continue;
                }
                Object value = FieldUtil.getGetter(field).invoke(t);
                if (value == null || "".equals(value.toString())) {
                    continue;
                }
                Object o = field.getType();
                if (((Class) o).isEnum()) {
                    o = Integer.class;
                }
                //多选条件
                if (isListSearch) {
                    Objects.requireNonNull(MappingContext.getMapping(List.class)).apply(t, field, queryWrapper);
                }else{
                    Objects.requireNonNull(MappingContext.getMapping((Class) o)).apply(t, field, queryWrapper);
                }
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                log.error("BaseServiceImpl.handleCondition", e);
            }
        }
    }

    // 获取指定字段下的最后一个数字的最大值，并+1
    public int extractAndFindMaxNumber(List<String> strings, String keyword) {
        int maxNumber = 0; //初始化为 0
        for (String str : strings) {
            if (str.contains(keyword)) {
                // 使用正则表达式提取最后一个数字
                String[] parts = str.split("-");
                String lastPart = parts[parts.length - 1];
                try {
                    int number = Integer.parseInt(lastPart);
                    // 比较并更新最大数字
                    if (number > maxNumber) {
                        maxNumber = number;
                    }
                } catch (NumberFormatException e) {
                    // 如果无法解析数字，忽略当前字符串
                }
            }
        }
        return maxNumber + 1;
    }

    //合同编号尾号+1
    public String incrementLastDigit(String input) {
        // 检查输入是否为空或不合法
        if (input == null || !input.matches(".*\\d$")) {
            throw new IllegalArgumentException("输入字符串不合法");
        }

        // 从字符串中提取数字部分
        String[] parts = input.split("-");
        String lastPart = parts[parts.length - 1];
        int lastDigit = Integer.parseInt(lastPart);

        // 将最后一个数字加1
        lastDigit++;

        // 将结果替换回原始字符串
        parts[parts.length - 1] = String.valueOf(lastDigit);
        StringBuilder result = new StringBuilder();
        for (String part : parts) {
            result.append(part).append("-");
        }

        // 移除最后一个多余的连字符
        result.deleteCharAt(result.length() - 1);

        return result.toString();
    }
}
